
import java.io.IOException;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.File;
import java.util.ArrayList;

public abstract class ReportWriter
{
    public String getReport(Team team, String title, Judicator j)
    {
        StringBuffer sb = new StringBuffer();
        writeHeader(sb, team, title);

        double[] pointsPerTask = calculatePoints(team,j);
        double[] maxPoints = getMaxPoints(j);
        String[] taskNames = getTaskNames(j);

        writeBreakdown(sb, team, taskNames, pointsPerTask, maxPoints);

        ArrayList<Issue> sortedIssues = getSortedIssues(team, j);

        writeIssues(sb, team, sortedIssues);

        return sb.toString();
    }

    public void writeReport(Team team, String title, Judicator j) throws IOException
    {
        File dir = new File(title);
        dir.mkdirs();

        PrintWriter pw = new PrintWriter(new FileWriter(title + "/" + getFilename(team, title)));
        System.out.println(title + "/" + getFilename(team, title));

        pw.write(getReport(team, title, j));

        pw.flush();
        pw.close();
    }

    private double[] calculatePoints(Team team, Judicator j)
    {
        double[] pts = new double[j.tasks.size()];
        for (int i = 0; i < pts.length; i++)
        {
            Task k = j.tasks.get(i);
            pts[i] = k.value;

            for (Issue s : j.issues)
            {
                if (s.teams.contains(team) && s.task == k)
                {
                    pts[i] += s.value;
                }
            }
            if (pts[i] < 0.0) pts[i] = 0.0;
        }
        return pts;
    }

    private String[] getTaskNames(Judicator j)
    {
        String[] names = new String[j.tasks.size()];
        for (int i = 0; i < names.length; i++)
        {
            names[i] = j.tasks.get(i).name;
        }
        return names;
    }

    private double[] getMaxPoints(Judicator j)
    {
        double[] pts = new double[j.tasks.size()];
        for (int i = 0; i < pts.length; i++)
        {
            pts[i] = j.tasks.get(i).value;
        }
        return pts;
    }

    private ArrayList<Issue> getSortedIssues(Team t, Judicator j)
    {
        ArrayList<Issue> byTask = new ArrayList<Issue>();
        ArrayList<Issue> out = new ArrayList<Issue>();

        for (int i = 0; i < j.tasks.size(); i++)
        {
            Task k = j.tasks.get(i);
            for (Issue s : t.issues)
            {
                if (s.task == k)
                {
                    byTask.add(s);
                }
            }

            out.addAll(byTask);
            byTask.clear();
        }

        return out;
    }

    protected abstract String getFilename(Team t, String title);
    protected abstract void writeHeader(StringBuffer sb, Team t, String title);
    protected abstract void writeBreakdown(StringBuffer sb, Team t, String[] taskNames,
                                           double[] points, double[] maxPoints);
    protected abstract void writeIssues(StringBuffer sb, Team t, ArrayList<Issue> sortedIssues);
}
